/**
 * Copyright 2007-2008. Chongqing First Information & Network Co., Ltd. All
 * rights reserved. <a>http://www.cqfirst.com.cn</a>
 */
package com.cqcis.uip.base.framework.handlers.common;

import com.cqcis.uip.base.framework.FrameworkConstants;
import com.cqcis.uip.base.framework.common.State;
import com.cqcis.uip.base.framework.common.Task;
import com.cqcis.uip.base.framework.core.AfterHandlerProcessResult;
import com.cqcis.uip.base.framework.core.RegisteredServiceContext;
import com.cqcis.uip.base.framework.core.Service;
import com.cqcis.uip.base.framework.core.TaskWaitTimeConsumePool;
import com.cqcis.uip.base.framework.utils.ConcurrentTaskQueue;
import com.cqcis.uip.base.framework.utils.TaskUtil;


/**
 * @author huangmy
 * @date   2008-1-12
 */
public abstract class AbstractHandler implements Service {		
	private ConcurrentTaskQueue<Task> taskQueue;            /*待处理任务队列*/ 
	private ConcurrentTaskQueue<Task> taskResultQueue; // 任务结果
	private ConcurrentTaskQueue<Task> sendTaskQueue; // 发送任务	
	private String interfaceId;   /*接口ID*/	
	private TaskWaitTimeConsumePool twtcp; // 任务超时等待池
	private AfterHandlerProcessResult afterResult;
	
	public void start(RegisteredServiceContext serviceContext) throws Exception {
		// do nothing
	}
	
	public void stop(RegisteredServiceContext serviceContext) throws Exception {
		// do nothing
	}
	
	public void registerAfterProcessResult(AfterHandlerProcessResult afterResult) {
		this.afterResult = afterResult;
	}
	
	protected AfterHandlerProcessResult getAfterResult() {
		return this.afterResult;
	}
	
	/**
	 * 异常结果
	 * 
	 * @param task
	 */
	protected void dispatchTaskExceptionResult(Task task, String message, Throwable t) {
		synchronized (task) {
			if (TaskUtil.isHasGenerateExceptionResult(task)) {
				return;
			}
			try {
				task.setMessage(message, t);
				task.setState(State.ERROR);
			    dispatchTaskResult(task, true); // 分发结果
			} finally {
			    TaskUtil.setHasGenerateExceptionResult(task);
			}
		}		
	}
	
	/**
	 * 处理任务结果
	 * 
	 * @param task
	 * @param exceptionResult 是否异常结果, 只对同步task有用
	 */
	protected void dispatchTaskResult(Task task, boolean exceptionResult) {					
		if (TaskUtil.isSyncTask(task)) {
			TaskUtil.createOrGetSyncCTQFor(task, FrameworkConstants.TASK_SYNCCTQ_FOR_RESULT).offer(task);
			if (exceptionResult) {
				TaskUtil.createOrGetSyncCTQFor(task, FrameworkConstants.TASK_SYNCCTQ_FOR_TASK).offer(task);
			}
		} else {
		    getTaskResultQueue().offer(task);	
		}
	}
	
	/**
	 * 任务ID, 惟一标识一个可控的任务;
	 * 可以为接口序列号、订单号或者业务号码.
	 */
	protected Task getTask() {		
		return taskQueue.poll();
	}
	
	/**
	 * 非阻塞获取任务, 没有则返回null
	 * 
	 * @return
	 */
	protected Task getTaskNoBlocking() {		
		return taskQueue.remove();
	}
	
	/**
	 * 处理被设置成again属性的task等待时间处理
	 * 
	 * @param task
	 */
	protected boolean doOperationForTimeConsumeIfAgain(Task task) {
		if (TaskUtil.isTaskStateInValid(task)) {
			return true;
		}
		
		if (TaskUtil.isTimeoutWaitState(task)) { // 如果task正在阻塞等待，则不处理
			return false;
		}
		
		if (task.isAgain() && TaskUtil.removePendingWait(task) && task.getWaitTime() > 0) {			
			if (task.getWaitTime() >= FrameworkConstants.MAXTIME_FOR_PUTTIMEOUTPOOL) {				
				this.twtcp.putTaskWait(task); // 放入等待池
				TaskUtil.setWaitTimePool(task, this.twtcp);				
				return false;
			} else {					
				TaskUtil.waitTimeoutDirect(task);
			}
		}
		
		return true;
	}
	
	public void registerTaskQueue(ConcurrentTaskQueue<Task> taskQueue) {
		this.taskQueue = taskQueue;
	}
	
	public void registerTaskResultQueue(ConcurrentTaskQueue<Task> taskResultQueue) {
		this.taskResultQueue = taskResultQueue;
	}
	
	public void registerSendTaskQueue(ConcurrentTaskQueue<Task> taskResultQueue) {
		this.sendTaskQueue = taskResultQueue;
	}
	
	protected ConcurrentTaskQueue<Task> getTaskResultQueue() {
		return taskResultQueue;
	}
	
	protected ConcurrentTaskQueue<Task> getTaskQueue() {
		return taskQueue;
	}
	
	protected ConcurrentTaskQueue<Task> getSendTaskQueue() {
		return sendTaskQueue;
	}
	
	public void registerInterfaceId(String interfaceId) {
    	this.interfaceId = interfaceId;
    }
	
	protected String getInterfaceId() {
		return this.interfaceId;
	}
	
	public void registerTaskWaitTimeConsumePool(TaskWaitTimeConsumePool twtcp) {
		this.twtcp = twtcp;
	}
}
